﻿using System.IO;

public static class SplitMergeBinaryFiles
{
    public static void SplitFile(string filePath)
    {
        using (FileStream fs = new FileStream(filePath,FileMode.Open))
        {
            int bufferSize = 8 * 4096;
            long size = fs.Length;
            long firstPartSize = size / 2;
            WriteFirstPart(firstPartSize, bufferSize, fs);
            WriteSecondPart(bufferSize, fs);
        }
    }
  
    private static void WriteFirstPart(long firstPartSize, int bufferSize, FileStream fs)
    {
        using (FileStream firstWriter = new FileStream(fs.Name + ".part1", FileMode.OpenOrCreate))
        {
            byte[] buffer = new byte[bufferSize];                
            while (fs.Position + bufferSize < firstPartSize)
            {
                int bytesRead = fs.Read(buffer, 0, bufferSize);
                firstWriter.Write(buffer, 0, bytesRead);
            }
            int lastBytes = fs.Read(buffer, 0, (int)(firstPartSize - fs.Position));
            firstWriter.Write(buffer, 0, lastBytes);
        }
    }

    private static void WriteSecondPart(int bufferSize, FileStream fs)
    {
        using (FileStream firstWriter = new FileStream(fs.Name + ".part2", FileMode.OpenOrCreate))
        {
            byte[] buffer = new byte[bufferSize];
            while (fs.Position < fs.Length)
            {
                int bytesRead = fs.Read(buffer, 0, bufferSize);
                firstWriter.Write(buffer, 0, bytesRead);
            }
        }
    }

    public static bool MergeFiles(string part1Path, string part2Path)
    {
        if (!File.Exists(part1Path)||!File.Exists(part2Path))
        {
            return false;
        }
        FileInfo p1 = new FileInfo(part1Path);
        string nameOfRestoredFile = p1.FullName+@".restored";
        using (FileStream combiner = new FileStream(nameOfRestoredFile,FileMode.OpenOrCreate))
        {
            int bufferSize = 8*4096;
            WritePartToResultFile(part1Path, bufferSize, combiner);
            WritePartToResultFile(part2Path, bufferSize, combiner);
        }
        return true;
    }
  
    private static void WritePartToResultFile(string part1Path, int bufferSize, FileStream combiner)
    {
        using (FileStream p1stream = new FileStream(part1Path, FileMode.Open))
        {
            byte[] buffer = new byte[bufferSize];
            while (p1stream.Position < p1stream.Length)
            {
                int bytesRead = p1stream.Read(buffer, 0, bufferSize);
                combiner.Write(buffer, 0, bytesRead);
            }
        }
    }
}